home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / networke / civ-0.000 / civ-0 / civ-0.3 / src / rules.cc < prev    next >
C/C++ Source or Header  |  1995-11-16  |  16KB  |  584 lines

  1. #include "misc.h"
  2. #include "rules.h"
  3. #include "hash.h"
  4. #include "list.h"
  5. #include "units.h"
  6. #include "debug.h"
  7. #include "player.h"
  8. #include "savefile.h"
  9. #include <string.h>
  10.  
  11. struct ObjectList
  12. {
  13.   char *name;
  14.   int type;
  15.   int unit;
  16.   int prodCost;
  17.   int maint;
  18. };
  19.  
  20. typedef List<charp> Strings;
  21.  
  22. char *science_list[] = {
  23.   "Advanced Flight", "Flight", "Electricity", NULL,
  24.   "Bomber", "Carrier", NULL,
  25.  
  26.   "Alphabet", NULL,
  27.   NULL,
  28.  
  29.   "Astronomy", "Mysticism", "Mathematics", NULL,
  30.   "Copernicus Observatory", NULL,
  31.  
  32.   "Atomic Theory", "Theory of Gravity", "Physics", NULL,
  33.   NULL,
  34.  
  35.   "Automobile", "Combustion", "Steel", NULL,
  36.   "Armor", NULL,
  37.  
  38.   "Banking", "Trade", "The Republic", NULL,
  39.   "Bank", NULL,
  40.  
  41.   "Bridge Building", "Iron Working", "Construction", NULL,
  42.   NULL,
  43.  
  44.   "Bronze Working", NULL,
  45.   "Phalanx", "Colossus", NULL,
  46.  
  47.   "Ceremonial Burial", NULL,
  48.   "Temple", NULL,
  49.  
  50.   "Chemistry", "University", "Medicine", NULL,
  51.   NULL,
  52.  
  53.   "Chivalry", "Feudalism", "Horseback Riding", NULL,
  54.   "Knights", NULL,
  55.  
  56.   "Code of Laws", "Alphabet", NULL,
  57.   "Courthouse", NULL,
  58.  
  59.   "Combustion", "Refining", "Explosives", NULL,
  60.   "Cruiser", NULL,
  61.  
  62.   "Communism", "Philosophy", "Industrialization", NULL,
  63.   "United Nations", NULL,
  64.  
  65.   "Computers", "Mathematics", "Electricity", NULL,
  66.   "SETI Program", NULL,
  67.  
  68.   "Conscription", "The Republic", "Explosives", NULL,
  69.   "Riflemen", NULL,
  70.  
  71.   "Construction", "Masonry", "Currency", NULL,
  72.   "Aquaduct", "Colosseum", NULL,
  73.  
  74.   "Currency", "Bronze Working", NULL,
  75.   "Marketplace", NULL,
  76.  
  77.   "Democracy", "Philosophy", "Literacy", NULL,
  78.   NULL,
  79.  
  80.   "Electricity", "Metallurgy", "Magnetism", NULL,
  81.   NULL,
  82.  
  83.   "Electronics", "Engineering", "Electricity", NULL,
  84.   "Hydro Plant", "Hoover Dam", NULL,
  85.  
  86.   "Engineering", "The Wheel", "Construction", NULL,
  87.   NULL,
  88.  
  89.   "Explosives", "Gunpowder", "Chemistry", NULL,
  90.   NULL,
  91.  
  92.   "Feudalism", "Masonry", "Monarchy", NULL,
  93.   NULL,
  94.  
  95.   "Flight", "Combustion", "Physics", NULL,
  96.   "Fighter", NULL,
  97.  
  98.   "Fusion Power", "Nuclear Power", "Superconductor", NULL,
  99.   "Fusion Plant", NULL,
  100.  
  101.   "Genetic Engineering", "Medicine", "The Corporation", NULL,
  102.   "Cure for Cancer", NULL,
  103.  
  104.   "Gunpowder", "Invention", "Iron Working", NULL,
  105.   "Musketeers", NULL,
  106.  
  107.   "Horseback Riding", NULL,
  108.   "Cavalry", NULL,
  109.  
  110.   "Industrialization", "Railroad", "Banking", NULL,
  111.   "Transport", "Factory", "Women's Suffrage", NULL,
  112.  
  113.   "Invention", "Engineering", "Literacy", NULL,
  114.   NULL,
  115.  
  116.   "Iron Working", "Bronze Working", NULL,
  117.   "Legion", NULL,
  118.  
  119.   "Labor Union", "Mass Production", "Communism", NULL,
  120.   "Mech. Infantry", NULL,
  121.  
  122.   "Literacy", "Writing", "Code of Laws", NULL,
  123.   "Great Library", NULL,
  124.  
  125.   "Magnetism", "Navigation", "Physics", NULL,
  126.   "Frigate", NULL,
  127.  
  128.   "Map Making", "Alphabet", NULL,
  129.   "Trireme", "Light House", NULL,
  130.  
  131.   "Masonry", NULL,
  132.   "Palace", "City Walls", "Pyramids", "Great Wall", NULL,
  133.  
  134.   "Mass Production", "Automobile", "The Corporation", NULL,
  135.   "Submarine", "Mass Transit", NULL,
  136.  
  137.   "Mathematics", "Alphabet", "Masonry", NULL,
  138.   "Catapult", NULL,
  139.  
  140.   "Medicine", "Philosophy", "Trade", NULL,
  141.   "Shakespeare's Theatre", NULL,
  142.  
  143.   "Metallurgy", "Gunpowder", "University", NULL,
  144.   "Cannon", NULL,
  145.  
  146.   "Monarchy", "Ceremonial Burial", "Code of Laws", NULL,
  147.   NULL,
  148.  
  149.   "Mysticism", "Ceremonial Burial", NULL,
  150.   "Oracle", NULL,
  151.  
  152.   "Navigation", "Map Making", "Astronomy", NULL,
  153.   "Sail", "Magellan's Expedition", NULL,
  154.  
  155.   "Nuclear Fission", "Mass Production", "Atomic Theory", NULL,
  156.   "Manhattan Project", NULL,
  157.  
  158.   "Nuclear Power", "Nuclear Fission", "Electronics", NULL,
  159.   "Nuclear Plant", NULL,
  160.  
  161.   "Philosophy", "Mysticism", "Literacy", NULL,
  162.   NULL,
  163.  
  164.   "Physics", "Mathematics", "Navigation", NULL,
  165.   NULL,
  166.  
  167.   "Plastics", "Refining", NULL,
  168.   NULL,
  169.  
  170.   "Pottery", NULL,
  171.   "Granary", "Hanging Gardens", NULL,
  172.  
  173.   "Railroad", "Bridge Building", "Steam Engine", NULL,
  174.   "Darwin's Voyage", NULL,
  175.  
  176.   "Recycling", "Mass Production", "Democracy", NULL,
  177.   "Recycling Ctr", NULL,
  178.  
  179.   "Refining", "Chemistry", "The Corporation", NULL,
  180.   "Power Plant", NULL,
  181.  
  182.   "Religion", "Philosophy", "Writing", NULL,
  183.   "Cathedral", "Michelangelo's Chapel", "J.S. Bach's Cathedral", NULL,
  184.  
  185.   "Robotics", "Plastics", "Computers", NULL,
  186.   "Artillery", "Mfg. Plant", NULL,
  187.  
  188.   "Rocketry", "Advanced Flight", "Electronics", NULL,
  189.   "Nuclear", NULL,
  190.  
  191.   "Steam Engine", "Physics", "Invention", NULL,
  192.   "Ironclad", NULL,
  193.  
  194.   "Steel", "Metallurgy", "Industrialization", NULL,
  195.   "Battleship", NULL,
  196.  
  197.   "Superconductor", "Plastics", "Mass Production", NULL,
  198.   "SDI Defense", NULL,
  199.  
  200.   "Survival", NULL,
  201.   "Settlers", "Militia", NULL,
  202.  
  203.   "The Corporation", "Banking", "Industrialization", NULL,
  204.   NULL,
  205.  
  206.   "The Republic", "Code of Laws", "Literacy", NULL,
  207.   NULL,
  208.  
  209.   "The Wheel", NULL,
  210.   "Chariot", NULL,
  211.  
  212.   "Theory of Gravity", "Astronomy", "University", NULL,
  213.   "Isaac Newton's College", NULL,
  214.  
  215.   "Trade", "Currency", "Code of Laws", NULL,
  216.   "Caravan", NULL,
  217.  
  218.   "University", "Mathematics", "Philosophy", NULL,
  219.   "University", NULL,
  220.  
  221.   "Writing", "Alphabet", NULL,
  222.   "Diplomat", "Library", NULL,
  223.  
  224.   NULL
  225.   };
  226.  
  227. ObjectList object_list[] = {
  228.   { "Armor", ARMOR, 1, 80, 0 },
  229.   { "Artillery", ARTILLERY, 1, 60, 0 },
  230.   { "Battleship", BATTLESHIP, 1, 160, 0 },
  231.   { "Bomber", BOMBER, 1, 120, 0 },
  232.   { "Cannon", CANNON, 1, 40, 0 },
  233.   { "Caravan", CARAVAN, 1, 50, 0 },
  234.   { "Carrier", CARRIER, 1,160, 0 },
  235.   { "Catapult", CATAPULT, 1, 40, 0 },
  236.   { "Cavalry", CAVALRY, 1, 20, 0 },
  237.   { "Chariot", CHARIOT, 1, 40, 0 },
  238.   { "Cruiser", CRUISER, 1, 80, 0 },
  239.   { "Diplomat", DIPLOMAT, 1, 30, 0 },
  240.   { "Fighter", FIGHTER, 1, 60, 0 },
  241.   { "Frigate", FRIGATE, 1, 40, 0 },
  242.   { "Ironclad", IRONCLAD, 1, 60, 0 },
  243.   { "Knights", KNIGHTS, 1, 40, 0 },
  244.   { "Legion", LEGION, 1, 20, 0 },
  245.   { "Mech. Infantry", MECH_INF, 1, 50, 0 },
  246.   { "Militia", MILITIA, 1, 10, 0 },
  247.   { "Musketeers", MUSKETEERS, 1, 30, 0 },
  248.   { "Nuclear", NUCLEAR, 1, 160, 0 },
  249.   { "Phalanx", PHALANX, 1, 20, 0 },
  250.   { "Riflemen", RIFLEMEN, 1, 30, 0 },
  251.   { "Sail", SAIL, 1, 40, 0 },
  252.   { "Settlers", SETTLER, 1, 40, 0 },
  253.   { "Submarine", SUBMARINE, 1, 50, 0 },
  254.   { "Transport", TRANSPORT, 1, 50, 0 },
  255.   { "Trireme", TRIREME, 1, 40, 0 },
  256.   { "Copernicus Observatory", COPERNICUS, 2, 300, 0 },
  257.   { "Bank", BANK, 0, 120, 3 },
  258.   { "Colossus", COLOSSUS, 2, 200, 0 },
  259.   { "Temple", TEMPLE, 0, 40, 1 },
  260.   { "Courthouse", COURTHOUSE, 0, 80, 1 },
  261.   { "United Nations", UNITEDNATIONS, 2, 600, 0 },
  262.   { "SETI Program", SETIPROGRAM, 2, 600, 0 },
  263.   { "Aquaduct", AQUADUCT, 0, 120, 2 },
  264.   { "Colosseum", COLOSSEUM, 0, 100, 3 },
  265.   { "Marketplace", MARKETPLACE, 0, 80, 1 },
  266.   { "Hydro Plant", HYDROPLANT, 0, 240, 4 },
  267.   { "Hoover Dam", HOOVERDAM, 2, 600, 0 },
  268.   { "Cure for Cancer", CUREFORCANCER, 2, 600, 0 },
  269.   { "Factory", FACTORY, 0, 200, 4 },
  270.   { "Women's Suffrage", WOMENSSUFFRAGE, 2, 600, 0 },
  271.   { "Great Library", GREATLIBRARY, 2, 300, 0 },
  272.   { "Light House", LIGHTHOUSE, 2, 200, 0 },
  273.   { "Palace", PALACE, 0, 100, 4 },
  274.   { "City Walls", CITYWALLS, 0, 120, 2 },
  275.   { "Pyramids", PYRAMIDS, 2, 300, 0 },
  276.   { "Great Wall", GREATWALL, 2, 300, 0 },
  277.   { "Mass Transit", MASSTRANSIT, 0, 160, 4 },
  278.   { "Shakespeare's Theatre", SHAKESPEARE, 2, 400, 0 },
  279.   { "Oracle", ORACLE, 2, 300, 0 },
  280.   { "Magellan's Expedition", MAGELLAN, 2, 400, 0 },
  281.   { "Manhattan Project", MANHATTAN, 2, 600, 0 },
  282.   { "Granary", GRANARY, 0, 60, 1 },
  283.   { "Hanging Gardens", HANGINGGARDENS, 2, 300, 0 },
  284.   { "Darwin's Voyage", DARWIN, 2, 300, 0 },
  285.   { "Recycling Ctr", RECYCLINGCTR, 0, 200, 2 },
  286.   { "Power Plant", POWERPLANT, 0, 160, 4 },
  287.   { "Fusion Plant", FUSIONPLANT, 0, 160, 4 },
  288.   { "Nuclear Plant", NUCLEARPLANT, 0, 200, 4 },
  289.   { "Cathedral", CATHEDRAL, 0, 160, 3 },
  290.   { "Michelangelo's Chapel", MICHELANGELO, 2, 300, 0 },
  291.   { "J.S. Bach's Cathedral", JSBACH, 2, 400, 0 },
  292.   { "Mfg. Plant", MFGPLANT, 0, 320, 6 },
  293.   { "SDI Defense", SDIDEFENSE, 0, 200, 4 },
  294.   { "Isaac Newton's College", ISAACNEWTON, 2, 400, 0 },
  295.   { "University", UNIVERSITY, 0, 160, 3 },
  296.   { "Library", LIBRARY, 0, 80, 1 },
  297.   { NULL, 0, 0, 0, 0 }
  298.   };
  299.  
  300. char *object_need_list[] = {
  301.   "University", "Library", NULL,
  302.   "Bank", "Marketplace", NULL,
  303.   "Power Plant", "Factory", NULL,
  304.   "Mfg. Plant", "Factory", NULL,
  305.   "Hydro Plant", "Factory", NULL,
  306.   "Nuclear Plant", "Factory", NULL,
  307.   "Fusion Plant", "Factory", NULL,
  308.   NULL
  309.   };
  310.  
  311. char *obselete_list[] = {
  312.   "Phalanx", "Militia",
  313.   "Cannon", "Catapult",
  314.   "Armor", "Cannon",
  315.   "Knights", "Chariot",
  316.   "Sail", "Trireme",
  317.   "Frigate", "Sail",
  318.   "Transport", "Frigate",
  319.   "Cruiser", "Ironclad",
  320.   "Musketeers", "Phalanx",
  321.   "Riflemen", "Musketeers",
  322.   NULL };
  323.  
  324. char *wonder_obsolete_list[] = {
  325.   "Pyramids", "Communism",
  326.   "Hanging Gardens", "Invention",
  327.   "Colossus", "Electricity",
  328.   "Light House", "Magnetism",
  329.   "Great Library", "University",
  330.   "Oracle", "Religion",
  331.   "Great Wall", "Gunpowder",
  332.   "Michelangelo's Chapel", "Communism",
  333.   "Copernicus Observatory", "Automobile",
  334.   "Shakespeare's Theatre", "Electronics",
  335.   "Isaac Newton's College", "Nuclear Fission",
  336.   NULL
  337.   };
  338.  
  339. HashTable<Science, StrKey> sciences(201);
  340. HashTable<BuildObject, StrKey> buildObjects(201);
  341.  
  342. // hashes on science, each object is a list of science names which
  343. // need the key science
  344. HashTable<Strings, StrKey> needTable(201);
  345.  
  346. List<charp> scienceNames;
  347.  
  348. char **NewScience(char **ptr)
  349. {
  350.   Science *sc = new Science;
  351.   sc->name = *ptr++;
  352.   sc->discovered = 0;
  353.   sc->wonderObsolete = NULL;
  354.   while (*ptr != NULL) {
  355.     char *name = *ptr++;
  356.     sc->need.Insert(name);
  357.  
  358.     Strings *strings = needTable.Find(StrKey(name));
  359.     if (strings == NULL) {
  360.       strings = new Strings;
  361.       needTable.Insert(strings, StrKey(name));
  362.     }
  363.     strings->Insert(sc->name); // sc->name depends on name
  364.   }
  365.   ++ptr; // get past NULL
  366.  
  367.   while (*ptr != NULL)
  368.     sc->canBuild.Insert(*ptr++);
  369.   ++ptr; // get past NULL
  370.   sciences.Insert(sc, StrKey(sc->name));
  371.   scienceNames.Insert(sc->name);
  372.   return ptr;
  373. }
  374.  
  375. ObjectList *NewObject(ObjectList *objList)
  376. {
  377.   BuildObject *obj = new BuildObject;
  378.   obj->name = objList->name;
  379.   obj->type = objList->type;
  380.   obj->unit = objList->unit == 1;
  381.   obj->wonder = objList->unit == 2;
  382.   obj->prodCost = objList->prodCost;
  383.   obj->maint = objList->maint;
  384.   obj->built = 0;
  385.   obj->isObsolete = 0;
  386.   obj->obsolete = NULL;
  387.   obj->line = new char[60];
  388.   if (obj->unit) {
  389.     // must match with selection handling  in player.cc
  390.     sprintf(obj->line, "%s %d/%d/%d  %d",obj->name, 
  391.         UnitAttack(obj->type),
  392.         UnitDefense(obj->type),
  393.         UnitMoves(obj->type),
  394.         obj->prodCost
  395.         );
  396.   } else 
  397.     // must match with selection handling  in player.cc
  398.     sprintf(obj->line, "%s %d",obj->name, 
  399.         obj->prodCost
  400.         );
  401.   buildObjects.Insert(obj, StrKey(obj->name));
  402.   ++objList;
  403.   return objList;
  404. }
  405.  
  406. void CheckRules()
  407. {
  408.   // for each science, check that the thing it needs is in the science
  409.   // table
  410.   // also check the things it can build are in the objects table
  411.   for (Lister<charp> lister = scienceNames; lister; lister.Next()) {
  412.     char *name = lister.Elem();
  413.     Science *sc = sciences.Find(StrKey(name));
  414.     Lister<charp> l = sc->need;
  415.     while (l) {
  416.       if (sciences.Find(StrKey(l.Elem())) == NULL)
  417.     Debug('r', "Science %s depends on non existant %s\n", name, l.Elem());
  418.       l.Next();
  419.     }
  420.     l = sc->canBuild;
  421.     while (l) {
  422.       if (buildObjects.Find(StrKey(l.Elem())) == NULL)
  423.     Debug('r', "Science %s can't build non existant %s\n", name, l.Elem());
  424.       l.Next();
  425.     }
  426.   }
  427. }
  428.  
  429. void InitializeRules()
  430. {
  431.   char **ptr = science_list;
  432.   while (*ptr != NULL)
  433.     ptr = NewScience(ptr);
  434.  
  435.   ObjectList *obj = object_list;
  436.   while (obj->name != NULL)
  437.     obj = NewObject(obj);
  438.  
  439.   ptr = object_need_list;
  440.   while (*ptr != NULL) {
  441.     BuildObject *obj = buildObjects.Find(StrKey(*ptr));
  442.     if (obj == NULL)
  443.       Debug('r', "Can't find object %s in InitializeRules\n", *ptr);
  444.     while (*++ptr != NULL)
  445.       obj->neededObj.Insert(*ptr);
  446.     ++ptr;
  447.   }
  448.   ptr = obselete_list;
  449.   while (*ptr != NULL) {
  450.     BuildObject *obj = buildObjects.Find(StrKey(*ptr++));
  451.     if (obj == NULL)
  452.       Debug('r', "Can't find %s in Obselete\n", *(ptr-1));
  453.     else
  454.       obj->obsolete = *ptr;
  455.     ++ptr;
  456.   }
  457.  
  458.   ptr = wonder_obsolete_list;
  459.   while (*ptr != NULL) {
  460.     BuildObject *obj = buildObjects.Find(StrKey(*ptr++));
  461.     if (obj == NULL)
  462.       Debug('r', "Can't find %s in obsolete\n", *(ptr-1));
  463.     Science *sc = sciences.Find(StrKey(*ptr++));
  464.     if (sc == NULL)
  465.       Debug('r', "Can't find %s in obsolete\n", *(ptr-1));
  466.     if (sc != NULL)
  467.       sc->wonderObsolete = obj->name;
  468.   }
  469.  
  470.   CheckRules();
  471. }
  472.  
  473. void CanDiscover(int player, char *science, List<charp> &canDiscover)
  474. {
  475.   Science *ptr = sciences.Find(StrKey(science));
  476.   int can = 1;
  477.   for (Lister<charp> needl = ptr->need; needl && can; needl.Next()) {
  478.     Science *ptr1 = sciences.Find(needl.Elem());
  479.     if (ptr1 != NULL)
  480.       can = ptr1->discovered & (1<<player);
  481.     else
  482.       can = players[player]->HasWonder(needl.Elem());
  483.   }
  484.   if (can)
  485.     canDiscover.Insert(ptr->name);
  486. }
  487.  
  488. void Discover(int player, char *science, List<charp> &discovered,
  489.           List<charp> &canDiscover, List<charp> &canBuild,
  490.           List<charp> &canGovern)
  491. {
  492.   Debug('r', "Discovering %s for %d\n", science, player);
  493.   Science *ptr = sciences.Find(StrKey(science));
  494.   science = ptr->name;
  495.   if (strcmp(science, "Mysticism") == 0)
  496.     players[player]->templeEffect = 2;
  497.  
  498.   if (strcmp(science, "Survival") == 0) canGovern.Insert("Despotism");
  499.   if (strcmp(science, "Monarchy") == 0)
  500.     canGovern.Insert("Monarchy");
  501.   if (strcmp(science, "The Republic") == 0)
  502.     canGovern.Insert("The Republic");
  503.   if (strcmp(science, "Democracy") == 0)
  504.     canGovern.Insert("Democracy");
  505.  
  506.   discovered.Insert(science);
  507.   Lister<charp> lister;
  508.   for (lister = canDiscover; lister; lister.Next())
  509.     if (strcmp(lister.Elem(), science) == 0) {
  510.       lister.Delete();
  511.       break;
  512.     }
  513.   ptr->discovered |= 1 << player;
  514.   if (ptr->wonderObsolete != NULL) {
  515.     BuildObject *wonder = buildObjects.Find(StrKey(ptr->wonderObsolete));
  516.     if (!wonder->isObsolete) {
  517.       wonder->isObsolete = 1;
  518.       AddMessage(players[playerId]->messages, "%s makes %s obsolete",
  519.          science, ptr->wonderObsolete);
  520.     }
  521.   }
  522.   Strings *strings = needTable.Find(StrKey(science));
  523.   if (strings != NULL) {
  524.     for (Lister<charp> stringl = *strings; stringl; stringl.Next()) {
  525.       CanDiscover(player, stringl.Elem(), canDiscover);
  526.     }
  527.   }
  528.   for (lister = ptr->canBuild; lister; lister.Next()) {
  529.     char *name = lister.Elem();
  530.     canBuild.Insert(name);
  531.     BuildObject *obj = buildObjects.Find(StrKey(name));
  532.     if (obj->obsolete != NULL) {
  533.       for (Lister<charp> l = canBuild; l; l.Next())
  534.     if (strcmp(l.Elem(), obj->obsolete) == 0) {
  535.       l.Delete();
  536.       break;
  537.     }
  538.     }
  539.   }
  540. }
  541.  
  542. void InitialScience(int player, List<charp> &discovered,
  543.             List<charp> &canDiscover, List<charp> &canBuild,
  544.             List<charp> &canGovern)
  545. {
  546.   Lister<charp> l = scienceNames;
  547.   // look for all sciences with an empty need list put into canDiscover
  548.   // and discover survival
  549.   while (l) {
  550.     Science *sc = sciences.Find(StrKey(l.Elem()));
  551.     if (!sc->need)
  552.       canDiscover.Insert(sc->name);
  553.     l.Next();
  554.   }
  555.   Discover(player, "Survival", discovered, canDiscover, canBuild, canGovern);
  556. }
  557.  
  558. // MarkM added variable discovery costs for sciences:
  559. // basically this was simply the recursive number of required sciences x15
  560. // however that was too fast so now trying 15 x (1+number already have)
  561. int DiscoverCost(int player, Science *ptr)
  562. {
  563. //  if (ptr == NULL) return 0;
  564. //  int cost = 15;
  565. //  for (Lister<charp> needl = ptr->need; needl; needl.Next()) {
  566. //    Science *ptr1 = sciences.Find(needl.Elem());
  567. //    if (ptr1 != NULL) cost += DiscoverCost(ptr1);
  568. //  }
  569. //  return cost;
  570.   return players[player]->discovered.Count() * 15;
  571. }
  572.  
  573. int Discovered(int player, char *science)
  574. {
  575.   Science *sc = sciences.Find(StrKey(science));
  576.   if (sc == NULL) return 0;
  577.   return sc->discovered & (1<<player);
  578. }
  579.  
  580. int WonderObsolete(BuildObject *wonder, int player)
  581. {
  582.   return wonder->isObsolete;
  583. }
  584.